/* 
 * cms，一个基于J2EE架构内容管理系统
 * Copyright © GrayRabbit Co., Ltd. All rights reserved.
 * Department:运营department
 * 更多信息请访问：
 * http://code.google.com/p/gray-rabbit-cms/
 */
package org.grayrabbit.cms.util;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Random;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * <b>UploadUtil</b>上传组件：
 * 

 * @version 1.0,创建时间: 2011-05-16 15:55:12
 */
public class UploadUtil {
	private static Logger log = LoggerFactory.getLogger(UploadUtil.class);

	private final static String imagePath = "/image";// 配置图片路径
	private final static String image_smallPath = "/image_small";// 配置小图片路径

	public String uploadImage(HttpServletRequest request, File getUpload,
			String getUploadContentType, String getUploadFileName)
			throws IOException {
		@SuppressWarnings("deprecation")
		String getImagePath = request.getRealPath(imagePath);
		@SuppressWarnings("deprecation")
		String getImage_smallPath = request.getRealPath(image_smallPath);

		File image = new File(getImagePath);
		if (!image.exists()) {
			image.mkdir();
		}
		File image_small = new File(getImage_smallPath);
		if (!image_small.exists()) {
			image_small.mkdir();
		}
		// 得到上传文件的后缀名
		// String uploadName = getUploadContentType;
		// String lastuploadName = uploadName.substring(uploadName.indexOf("/")
		// + 1, uploadName.length());
		// 得到文件的新名字
		String fileNewName = generateFileName(getUploadFileName);

		FileOutputStream fos = new FileOutputStream(getImagePath + "/"
				+ fileNewName);
		FileInputStream fis = new FileInputStream(getUpload);
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = fis.read(buffer)) > 0) {
			fos.write(buffer, 0, len);
		}
		// DwindlePic mypic = new DwindlePic();
		// s_pic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度)
		// mypic.s_pic(getImagePath + "/", getImage_smallPath + "/",
		// fileNewName,fileNewName, 120, 80, true);

		return imagePath + "/" + fileNewName;

	}

	/**
	 * 以yyMMddHHmmss加随即数进行重命名时间
	 * 
	 * @param fileName
	 * @return
	 */
	public String generateFileName(String fileName) {
		DateFormat format = new SimpleDateFormat("yyMMddHHmmss");
		String formatDate = format.format(new Date());
		int random = new Random().nextInt(10000);
		int position = fileName.lastIndexOf(".");
		String extension = fileName.substring(position);
		return formatDate + random + extension;
	}

	/**
	 * 图片大小转换
	 * 
	 * @param InputDir输入图片路径
	 * @param OutputDir输出图片路径
	 * @param InputFileName输入图片名称
	 * @param OutputFileName输出图片名称
	 * @param width图片宽度
	 * @param height图片高度
	 */
	public static File dealWithPic(String inputDir, String outputDir,
			String inputFileName, String outputFileName, int width, int height) {
		try {
			File file = new File(inputDir+inputFileName);
			Image src = ImageIO.read(file);
			BufferedImage image = new BufferedImage(width, height,
					BufferedImage.TYPE_INT_RGB);
			Graphics g = image.createGraphics();
			g.drawImage(src, 0, 0, width, height, null);
			g.dispose();
			FileOutputStream out = new FileOutputStream(outputDir+outputFileName);
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			encoder.encode(image);
			out.close();
		} catch (Exception e) {
			log.error("",e);
		}
		return new File(outputDir+outputFileName);
	}
	
	/**
	 * 判断是否为图片文件
	 * @param fileName
	 * @return
	 */
	public static boolean isPic(String fileName,String picType){
		boolean rs = false;
		if(StringUtils.isNotBlank(FileUtil.getFileExt(fileName))){
			for(String pt:picType.trim().split("\\|")){
				if(FileUtil.getFileExt(fileName).toUpperCase().equals(pt.toUpperCase())){
					rs = true;
				}
			}
			return rs;
		}else{
			return false;
		}
	}

	/**
	 * zip压缩功能测试. 将d:\\temp\\zipout目录下的所有文件连同子目录压缩到d:\\temp\\out.zip.
	 * 
	 * @param baseDir
	 *            所要压缩的目录名（包含绝对路径）
	 * @param objFileName
	 *            压缩后的文件名
	 * @throws Exception
	 */
	public static void createZip(String baseDir, String objFileName)
			throws Exception {
		File folderObject = new File(baseDir);
		if (folderObject.exists()) {
			List<File> fileList = getSubFiles(new File(baseDir));
			// 压缩文件名
			ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(
					objFileName));
			ZipEntry ze = null;
			byte[] buf = new byte[1024];
			int readLen = 0;
			for (int i = 0; i < fileList.size(); i++) {
				File f = (File) fileList.get(i);
				// 创建一个ZipEntry，并设置Name和其它的一些属性
				ze = new ZipEntry(getAbsFileName(baseDir, f));
				ze.setSize(f.length());
				ze.setTime(f.lastModified());
				// 将ZipEntry加到zos中，再写入实际的文件内容
				zos.putNextEntry(ze);
				InputStream is = new BufferedInputStream(new FileInputStream(f));
				while ((readLen = is.read(buf, 0, 1024)) != -1) {
					zos.write(buf, 0, readLen);
				}
				is.close();
			}
			zos.close();
		} else {
			throw new Exception("this folder isnot exist!");
		}
	}

	private static List<File> getSubFiles(File baseDir) {
		List<File> ret = new ArrayList<File>();
		File[] tmp = baseDir.listFiles();
		for (int i = 0; i < tmp.length; i++) {
			if (tmp[i].isFile()) {
				ret.add(tmp[i]);
			}
			if (tmp[i].isDirectory()) {
				ret.addAll(getSubFiles(tmp[i]));
			}
		}
		return ret;
	}

	private static String getAbsFileName(String baseDir, File realFileName) {
		File real = realFileName;
		File base = new File(baseDir).getParentFile();
		String ret = real.getName();
		while (true) {
			real = real.getParentFile();
			if (real == null)
				break;
			if (real.equals(base))
				break;
			else {
				ret = real.getName() + "/" + ret;
			}
		}
		return ret;
	}

	/**
	 * 测试解压缩功能. 将d:\\download\\test.zip连同子目录解压到d:\\temp\\zipout目录下.
	 * 
	 * @throws Exception
	 */
	public static void releaseZipToFile(String sourceZip, String outFileName)
			throws IOException {
		ZipFile zfile = new ZipFile(sourceZip);
		@SuppressWarnings("rawtypes")
		Enumeration zList = zfile.entries();
		ZipEntry ze = null;
		byte[] buf = new byte[1024];
		while (zList.hasMoreElements()) {
			// 从ZipFile中得到一个ZipEntry
			ze = (ZipEntry) zList.nextElement();
			if (ze.isDirectory()) {
				continue;
			}
			// 以ZipEntry为参数得到一个InputStream，并写到OutputStream中
			OutputStream os = new BufferedOutputStream(new FileOutputStream(
					getRealFileName(outFileName, ze.getName())));
			InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
			int readLen = 0;
			while ((readLen = is.read(buf, 0, 1024)) != -1) {
				os.write(buf, 0, readLen);
			}
			is.close();
			os.close();
		}
		zfile.close();

	}

	/**
	 * 给定根目录，返回一个相对路径所对应的实际文件名.
	 * 
	 * @param baseDir
	 *            指定根目录
	 * @param absFileName
	 *            相对路径名，来自于ZipEntry中的name
	 * @return java.io.File 实际的文件
	 */
	private static File getRealFileName(String baseDir, String absFileName) {
		String[] dirs = absFileName.split("/");
		File ret = new File(baseDir);
		if (dirs.length > 1) {
			for (int i = 0; i < dirs.length - 1; i++) {
				ret = new File(ret, dirs[i]);
			}
		}
		if (!ret.exists()) {
			ret.mkdirs();
		}
		ret = new File(ret, dirs[dirs.length - 1]);
		return ret;
	}

}
